Lambdaを使ってS3にアップロードされたファイルを自動的にEC2(Windows)内にダウンロード(同期)してみる
どうも!大阪オフィスの西村祐二です。
S3にアップロードされたファイルをEC2内に自動的にダウンロードしたいと思うことはよくあると思います。 自動化する方法はいろいろあると思いますが、 今回はLambdaとSSM、AWS CLIを使って自動化してみたいと思います。
さっそくやってみましょう。
構成図
今回、想定する構成が下記の図になります。
S3にファイルがアップロードされたら、LambdaからSSMを実行し、
EC2(Windows)にてAWSCLIのS3 Sync
コマンドを実行します。
この構成の利点
私が思うこの構成の利点としては、 ・EC2側はAWS CLI設定とSSM Agentのインストールだけで済み、今後の運用不可が軽減されそう ・Lambdaの実装がSSMを実行する部分のみになる
はじめはEC2にFTPサーバをたてて、LambdaでS3からファイルを取得し、EC2にコピーしようと思いましたが、 FTPサーバを立ててしまうと、FTPサーバの設定や、ポート、FTPログなど 新たに管理しなければいけない項目が増えてしまいそうだと思い、、 また、コピーする際にLambdaの制限を考慮したり、EC2へのログイン処理など すこし大袈裟な処理になりそうでしたので、今回はシンプルにLambdaはSSMを実行するだけとし S3にアップロードされたファイルはEC2から取得する構成としてみました。
環境
■Windows: Windows Server 2016
■セキュリティグループ:
インバウンドは作業用にマイIPのみ許可しています。
■Lambda:
・ランタイム:python3.6
作業概要
■EC2(Windows):
・AWS CLI環境を構築する ・SSM Agentをインストールし、設定する
■Lambda:
・S3へのアップロードをトリガーとするLambdaからSSMを実行する関数を作成する
EC2(Windows)の作業:AWS CLI環境を構築する
同期用のIAMユーザを作成する
今回、EC2からS3のファイルをダウンロードするため、 まず、S3への権限を付与したIAMユーザを作っておきましょう。 既存のユーザがあるなら、そちらでも大丈夫です。
▼マネージメントコンソールからIAMのサービス画面に移動し、「ユーザを追加」をクリックします
▼ユーザ名を「test-s3-sync」として、「プログラムによるアクセス」にチェックします
▼アクセス権限はS3へのアクセスを許可するポリシーをアタッチしておきます
▼CSVをダウンロードしておき、アクセスキーIDとシークレットアクセスキーをメモしておきます
EC2(Windows)にてAWS CLIを設定する
▼下記ドキュメントを参考にAWS CLIをインストールします。
Microsoft Windows で AWS Command Line Interface をインストールする
インストールが完了したらpowershellなどで下記コマンドを実行し、AWS CLIの情報が出力されるか確認します。
> aws --version aws-cli/1.11.189 Python/2.7.9 Windows/2012Server botocore/1.7.47
▼プロファイルの設定をします。
powershellから
aws configure --profile s3-sync-user
と入力して設定していきます。
今回はプロファイル名「s3-sync-user」として設定しています。
AWS Access Key ID
と
AWS Secret Access Key
には、ダウンロードしたCSVに記載されていた値を入力します。
▼動作確認を行います。
設定がうまくいっていれば、aws s3 ls s3://<バケット名> --profile s3-sync-user
で
S3のバケットの中身が確認できます。
EC2(Windows)の作業:SSM Agentをインストールし、設定する
下記ドキュメントを参考にSSM Agentをインストールします。
Windows インスタンスで SSM エージェント をインストールし設定する
EC2用のIAMロールを設定する
▼EC2とSSMがアクセスするために、EC2にIAMロールを設定します。
▼作成した「test-ssm」を選択し、EC2にIAMロールを設定します。
▼SSMのAgentやIAMの設定が完了したら、きちんと認識されているか確認します。
▼認識されていたら、画像のようにインスタンスIDがみえます。
Lambda関数を作成します
下記がサンプルプログラムになります。 対象のインスタンスIDと、EC2で実行してほしいコマンドを設定します。
今回はAWS-RunPowerShellScript
を使って
EC2内のデスクトップにある、「s3-sync」というフォルダに
S3のバケット内のファイルをダウンロードします。
EC2内で実行されるコマンド
aws s3 sync s3:// C:\Users\Administrator\Desktop\s3-sync\
また、対象のバケットをトリガーとする設定と、IAMにはEC2とSSMの権限を付与しておいてください。
"""This is a test program.""" import logging import boto3 LOGGER = logging.getLogger() LOGGER.setLevel(logging.INFO) EC2 = boto3.client('ec2') SSM = boto3.client('ssm') INSTANCE_ID = 'i-0XXXXXXXXXXXXX' def lambda_handler(event, context): """ Run 'S3 sync command'in Windows from Lambda """ try: # Get EC2 State ec2_resp = EC2.describe_instances(InstanceIds=[INSTANCE_ID]) ec2_state = ec2_resp['Reservations'][0]['Instances'][0]['State']['Name'] if not ec2_state == "running": LOGGER.info('No EC2 is running') return "END" # RunPowerShellScript command = r'aws s3 sync s3://<your target bucket> C:\Users\Administrator\Desktop\s3-sync\ ' SSM.send_command( InstanceIds=[INSTANCE_ID], DocumentName="AWS-RunPowerShellScript", Parameters={ "commands":[command], "executionTimeout":["3600"] }, ) except Exception as error: LOGGER.error(error) raise error
動作確認
トリガーとなるバケットにファイルをアップロードし、EC2へ同期されるか確認してみます。
想定通り、バケットへファイルを追加すると、右側のEC2のフォルダでもファイルがふえていることがわかります。
さいごに
いかがだったでしょうか。
Lambdaを使ってS3にアップロードされたファイルを自動的にEC2(Windows)内にダウンロード(同期)してみました。 EC2にてAWS CLIの設定と、SSM Agentのインストールを行えば、簡単に実現することができます。 要件次第ではありますが、FTPサーバを利用するより運用コストも軽微で済むのではないでしょうか。
誰かの参考になれば幸いです。